package com.flying.flyingchessgame.security.jwt;

import io.jsonwebtoken.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.security.core.Authentication;
import org.springframework.stereotype.Component;

import com.flying.flyingchessgame.security.service.UserDetailsImpl;

import java.util.Date;

/**
 * JWT工具类
 * <p>
 * 提供JWT令牌的生成、解析和验证功能。
 * JWT（JSON Web Token）用于实现基于令牌的身份验证。
 * </p>
 * 
 * @author flying-chess
 * @version 1.0
 */
@Component
public class JwtUtils {
    private static final Logger logger = LoggerFactory.getLogger(JwtUtils.class);

    /**
     * JWT密钥，从配置文件中注入
     */
    @Value("${jwt.secret}")
    private String jwtSecret;

    /**
     * JWT过期时间（毫秒），从配置文件中注入
     */
    @Value("${jwt.expiration}")
    private int jwtExpirationMs;

    /**
     * 生成JWT令牌
     * <p>
     * 根据用户认证信息生成包含用户名的JWT令牌。
     * </p>
     *
     * @param authentication 认证信息
     * @return JWT令牌字符串
     */
    public String generateJwtToken(Authentication authentication) {
        UserDetailsImpl userPrincipal = (UserDetailsImpl) authentication.getPrincipal();
        
        logger.debug("为用户生成JWT令牌: {}", userPrincipal.getUsername());
        
        Date now = new Date();
        Date expiryDate = new Date(now.getTime() + jwtExpirationMs);
        
        logger.debug("令牌过期时间: {}", expiryDate);

        return Jwts.builder()
                .setSubject(userPrincipal.getUsername())
                .setIssuedAt(now)
                .setExpiration(expiryDate)
                .signWith(SignatureAlgorithm.HS512, jwtSecret)
                .compact();
    }

    /**
     * 从JWT令牌中获取用户名
     *
     * @param token JWT令牌
     * @return 用户名
     */
    public String getUsernameFromJwtToken(String token) {
        String username = Jwts.parser().setSigningKey(jwtSecret).parseClaimsJws(token).getBody().getSubject();
        logger.trace("从JWT令牌获取用户名: {}", username);
        return username;
    }

    /**
     * 验证JWT令牌是否有效
     *
     * @param authToken JWT令牌
     * @return 如果令牌有效返回true，否则返回false
     */
    public boolean validateJwtToken(String authToken) {
        try {
            Jwts.parser().setSigningKey(jwtSecret).parseClaimsJws(authToken);
            return true;
        } catch (SignatureException e) {
            logger.error("无效的JWT签名: {}", e.getMessage());
        } catch (MalformedJwtException e) {
            logger.error("无效的JWT令牌: {}", e.getMessage());
        } catch (ExpiredJwtException e) {
            logger.error("JWT令牌已过期: {}", e.getMessage());
        } catch (UnsupportedJwtException e) {
            logger.error("不支持的JWT令牌: {}", e.getMessage());
        } catch (IllegalArgumentException e) {
            logger.error("JWT令牌声明为空: {}", e.getMessage());
        }

        return false;
    }
} 